package galatea;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class TextWindow extends JTextPane{
	StyledDocument doc;
	ArrayList<String> types, functions, keywords;
	
	TextWindow(){
		this.setDragEnabled(true);
		doc = this.getStyledDocument();
		
		Style style = this.addStyle("Blue", null);
		StyleConstants.setForeground(style, Color.blue);
		
		style = this.addStyle("Type", null);
		StyleConstants.setForeground(style, Color.blue);
		
		style = this.addStyle("Purple", null);
		StyleConstants.setForeground(style, Color.magenta.darker());
		
		style = this.addStyle("Black", null);
		StyleConstants.setForeground(style, Color.black);
		
		style = this.addStyle("Green", null);
		StyleConstants.setForeground(style, Color.green.darker());
		
		style = this.addStyle("Orange", null);
		StyleConstants.setForeground(style, Color.orange.darker());
		
		functions = new ArrayList<String>();
		
		types = new ArrayList<String>();
		types.add("void");
		types.add("int");
		types.add("bool");
		types.add("double");
		types.add("char");
		types.add("float");
		
		keywords = new ArrayList<String>();
		keywords.add("new");
		keywords.add("delete");
		keywords.add("if");
		keywords.add("else");
		keywords.add("else if");
		keywords.add("while");
		keywords.add("do");
		keywords.add("for");
		keywords.add("switch");
		keywords.add("case");
		keywords.add("signed");
		keywords.add("unsigned");
		keywords.add("true");
		keywords.add("false");
		keywords.add("#include");
		keywords.add("#define");
		keywords.add("class");
	}
	
	Runnable doWorkRunnable = new Runnable() {
	    public void run() { autoformat(); }
	};
	
	void autoformat(){/*
		System.out.println("Autoformatting");
		String text = this.getText();
		
		int index = text.indexOf("void ");
		if (index > 0)
			doc.setCharacterAttributes(index, 4, this.getStyle("Blue"), true);
			*/
		doc.setCharacterAttributes(0, this.getText().length(), this.getStyle("Black"), true);
		
		functions.clear();
		
		for (String t:types)
			highlightSyntax(t, "Type", 0);
		for (String k:keywords)
			highlightSyntax(k, "Blue", 0);
		
		if (!functions.isEmpty()){
			for (String f:functions)
				highlightSyntax(f, "Purple", 0);
		}
		
		highlightSyntax("\"", "\"", "Orange", 0);
		//highlightSyntax("<", ">", "Orange", 0);
		highlightSyntax("//", "\n", "Green", 0);
		highlightSyntax("/*", "*/", "Green", 0);
	}
	
	void autoModulate(){
		
	}
	
	void highlightSyntax(String word, String style, int index){
		String text = this.getText();
		int loc = text.indexOf(word, index);
		
		if ((loc != -1)//The index of the word exists

		){
			//System.out.println(text.charAt(loc + word.length()));
			
			if (((loc + word.length() < text.length()) && //If the word is not the last character
				!(isChar(text.charAt(loc + word.length()))) || //The next character is not number or letter
				(loc + word.length() >= text.length())) &&//If the word is the last character then highlight
				((loc == 0) || (loc > 0 && !isChar(text.charAt(loc-1))))) //If the word is not the first word, then check if it is the end of a bigger word
				{
					doc.setCharacterAttributes(loc, word.length(), this.getStyle(style), true);
					if (style == "Type"){
						highlightFunctions(word, loc);
						autoModulate();
					}
				}
	
			if (loc + word.length() < text.length()){
				//System.out.println(word);
				//System.out.println(loc);
				highlightSyntax(word, style, loc + word.length());
			}
		}
	}
	
	void highlightSyntax(String startWord, String endWord, String style, int index){
		String text = this.getText();
		int loc1 = text.indexOf(startWord, index);
		
		if (loc1 != -1){
			int loc2 = text.indexOf(endWord, loc1+1);
			if (loc2 != -1){
				doc.setCharacterAttributes(loc1, loc2-loc1+1, this.getStyle(style), true);
				highlightSyntax(startWord, endWord, style, loc2+1);
			}
			else
				doc.setCharacterAttributes(loc1, text.length()-loc1, this.getStyle(style), true);
		}
	}
	
	void highlightFunctions(String word, int loc){
		String text = this.getText();
		
		if (((loc + word.length() + 1) <= text.length()) && 
				((text.charAt(loc + word.length()) == ' ') || (text.charAt(loc + word.length()) == '\t')) && 
				(text.charAt(loc + word.length() + 1) != '(')){
			int parIndex = text.indexOf('(', loc + word.length() + 1);
			int spaceIndex = text.indexOf(' ', loc + word.length() + 1);
			
			if (parIndex > -1 && (parIndex < spaceIndex || spaceIndex == -1)){
				functions.add(text.substring(loc + word.length() + 1, parIndex));
			}
		}
	}

	boolean isChar(char c){
		switch(c){
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case '0':
			return true;
		default:
			return false;
		}
	}
	

}